﻿using agsXMPP;
using agsXMPP.protocol.client;
using JBotAPI.Logs;
using ScriptsAPI;
using System;
using System.Windows;
using System.Windows.Threading;

namespace JBot {
	/// <summary>
	/// Interaction logic for MainWindow.xaml
	/// </summary>
	public partial class MainWindow : Window {
		public MainWindow( ) {
			this.InitializeComponent( );
			this.StateBot("Loading", false);
			setEvents( );
			resetXMPP( );
			this.StateBot("Runing", false);
			App.NotifyIcon.Visible = true;
			App.NotifyIcon.DoubleClick += new EventHandler(notifyIcon_DoubleClick);
		}

		private void notifyIcon_DoubleClick(object sender, EventArgs e) {
			if (!this.Dispatcher.CheckAccess( )) {
				this.Dispatcher.Invoke(new EventHandler(notifyIcon_DoubleClick), sender, e);
			} else {
				SHwindow( );
			}
		}
		//Dialog.SetDescBox SD;
		Windows.OptionsWindow Options;
		Windows.UpdateWindow Updates;
		Windows.AboutWindow About;

		private void resetXMPP( ) {
			XmppConnectionState connectionState = App.xmpp.XmppConnectionState;
			if (connectionState != XmppConnectionState.Disconnected)
				App.xmpp.disconnect( );

			App.xmpp.Username = Properties.Settings.Default.Login;
			App.xmpp.Server = Properties.Settings.Default.Server;
			App.xmpp.Password = Properties.Settings.Default.Password;
			App.xmpp.Port = Properties.Settings.Default.Port;
			App.xmpp.Show = Properties.Settings.Default.PShow;
			App.xmpp.Status = Properties.Settings.Default.Status;

			App.xmpp.RegisterAccount = Properties.Settings.Default.RegisterAccount;
			App.xmpp.AutoResolveConnectServer = Properties.Settings.Default.AutoResolveConnectServer;
			App.xmpp.AutoAgents = Properties.Settings.Default.AutoAgents;
			App.xmpp.AutoRoster = Properties.Settings.Default.AutoRoster;
			App.xmpp.KeepAlive = Properties.Settings.Default.KeepAlive;
			App.xmpp.KeepAliveInterval = Properties.Settings.Default.KeepAliveInterval;
			App.xmpp.UseSSL = Properties.Settings.Default.UseSSL;
			App.xmpp.UseStartTLS = Properties.Settings.Default.UseStartTLS;
			App.xmpp.Priority = Properties.Settings.Default.Priority;
			App.xmpp.ClientVersion = Properties.Settings.Default.ClientVersion;
			App.xmpp.Resource = Properties.Settings.Default.Resource;

			//Global.xmpp.loadTemp(Properties.Settings.Default.Login, Properties.Settings.Default.Server, Properties.Settings.Default.Resource, Properties.Settings.Default.Status, Properties.Settings.Default.PShow, Properties.Settings.Default.PType);
			//Global.xmpp.loadXMPP(Properties.Settings.Default.Login, Properties.Settings.Default.Server, Properties.Settings.Default.Password, Properties.Settings.Default.Port, Properties.Settings.Default.PShow, Properties.Settings.Default.Status, Properties.Settings.Default.RegisterAccount, Properties.Settings.Default.AutoResolveConnectServer, Properties.Settings.Default.AutoAgents, Properties.Settings.Default.AutoRoster, Properties.Settings.Default.KeepAlive, Properties.Settings.Default.KeepAliveInterval, Properties.Settings.Default.UseSSL, Properties.Settings.Default.UseStartTLS, Properties.Settings.Default.Priority, Properties.Settings.Default.ClientVersion, Properties.Settings.Default.Resource);

			if (connectionState != XmppConnectionState.Disconnected)
				App.xmpp.connect( );
		}
		protected void setEvents( ) {
			App.xmpp.OnIq += new IqHandler(xmpp_OnIq);
			App.xmpp.OnLogin += new ObjectHandler(xmpp_OnLogin);
			App.xmpp.OnMessage += new MessageHandler(xmpp_OnMessage);
			App.xmpp.OnPresence += new PresenceHandler(xmpp_OnPresence);
			//XMPP.CCXMPP.OnReadSocketData += new agsXMPP.net.BaseSocket.OnSocketDataHandler(xmpp_OnReadSocketData);
			//Global.xmpp.OnRosterEnd += new ObjectHandler(xmpp_OnRosterEnd);
			//Global.xmpp.OnRosterItem += new XmppClientConnection.RosterHandler(xmpp_OnRosterItem);
			//XMPP.CCXMPP.OnWriteSocketData += new agsXMPP.net.BaseSocket.OnSocketDataHandler(xmpp_OnWriteSocketData);
			App.xmpp.OnXmppConnectionStateChanged += new XmppConnectionStateHandler(xmpp_OnXmppConnectionStateChanged);
			App.xmpp.OnError += new ErrorHandler(xmpp_OnError);
			App.xmpp.OnSocketError += new ErrorHandler(xmpp_OnSocketError);
			App.xmpp.OnStreamError += new XmppElementHandler(xmpp_OnStreamError);
		}

		private void xmpp_OnError(object sender, Exception ex) {
			if (!this.Dispatcher.CheckAccess( )) {
				this.Dispatcher.Invoke(new ErrorHandler(xmpp_OnError), DispatcherPriority.Normal, new object[ ] { sender, ex });
			} else {
			}
		}
		private void xmpp_OnSocketError(object sender, Exception ex) {
			if (!this.Dispatcher.CheckAccess( )) {
				this.Dispatcher.Invoke(new ErrorHandler(xmpp_OnSocketError), DispatcherPriority.Normal, new object[ ] { sender, ex });
			} else {
				switch (App.xmpp.XmppConnectionState) {
					case XmppConnectionState.Connecting:
						this.xmpp_OnXmppConnectionStateChanged(this, agsXMPP.XmppConnectionState.Disconnected);
						this.SBI_LS_XMPP.Content = "Connection error";
						break;
				}
			}
		}
		private void xmpp_OnStreamError(object sender, agsXMPP.Xml.Dom.Element e) {
			if (!this.Dispatcher.CheckAccess( )) {
				this.Dispatcher.Invoke(new XmppElementHandler(xmpp_OnStreamError), DispatcherPriority.Normal, new object[ ] { sender, e });
			} else {
			}
		}

		#region Zdarzenia XMPP
		public void xmpp_OnIq(object sender, agsXMPP.protocol.client.IQ iq) {
			if (!this.Dispatcher.CheckAccess( )) {
				this.Dispatcher.Invoke(new IqHandler(xmpp_OnIq), DispatcherPriority.Normal, new object[ ] { sender, iq });
			} else {
				// MessageBox.Show(iq.ToString());
				if (iq.Type == IqType.error) {
					if (iq.NodeType == agsXMPP.Xml.Dom.NodeType.Text) {

					}
				}
			}
		}
		public void xmpp_OnLogin(object sender) {
			if (!this.Dispatcher.CheckAccess( )) {
				this.Dispatcher.Invoke(new ObjectHandler(xmpp_OnLogin), DispatcherPriority.Normal, new object[ ] { sender });
			} else {
				/* Ustanowiono połączenie z serwerem */
				Presence p = new Presence(App.xmpp.Me.ShowType, App.xmpp.Me.Status);
				p.Type = App.xmpp.Me.PresenceType;
				App.xmpp.sendXml(p);
			}
		}
		public void xmpp_OnMessage(object sender, agsXMPP.protocol.client.Message msg) {
			if (!this.Dispatcher.CheckAccess( )) {
				this.Dispatcher.Invoke(new MessageHandler(xmpp_OnMessage), DispatcherPriority.Normal, new object[ ] { sender, msg });
			} else {
				/* Przyszła nowa wiadomość. */
				if (msg != null)
					BotScripts.on_Message(msg.From.ToString( ), msg.Body, msg.Subject, msg.Thread, DateTime.Now, JFunctions.msgTypeToInt(msg.Type));
			}
		}
		public void xmpp_OnPresence(object sender, Presence pres) {
			if (!this.Dispatcher.CheckAccess( )) {
				this.Dispatcher.Invoke(new PresenceHandler(xmpp_OnPresence), DispatcherPriority.Normal, new object[ ] { sender, pres });
			} else {
				/* Zwrucono status kontaktu */
				if (pres.From.ToString( ) == App.xmpp.Me.Jid.ToString( ))
					CheckStatus(pres);
				BotScripts.on_Presence(pres.From.ToString( ), JFunctions.getStatusInt(pres), pres.Status, null, null, 0);
			}
		}
		public void xmpp_OnXmppConnectionStateChanged(object sender, agsXMPP.XmppConnectionState state) {
			if (!this.Dispatcher.CheckAccess( )) {
				this.Dispatcher.Invoke(new XmppConnectionStateHandler(xmpp_OnXmppConnectionStateChanged), DispatcherPriority.Normal, new object[ ] { sender, state });
			} else {
				switch (state) {
					case XmppConnectionState.Authenticated:
						break;
					case XmppConnectionState.Authenticating:
						break;
					case XmppConnectionState.Binded:
						break;
					case XmppConnectionState.Binding:
						break;
					case XmppConnectionState.Compressed:
						break;
					case XmppConnectionState.Connected:
						this.MW_M_B_Co.IsChecked = true;
						this.MW_M_B_Ch.IsEnabled = true;
						this.MW_TC_Ct.IsEnabled = true;
						this.MW_TC_S.IsEnabled = true;
						this.ControlCt.IsEnabled = true;
						this.ControlS.IsEnabled = true;
						break;
					case XmppConnectionState.Connecting:
						break;
					case XmppConnectionState.Disconnected:
						this.MW_M_B_Co.IsChecked = false;
						this.MW_M_B_Ch.IsEnabled = false;
						this.MW_TC_Ct.IsEnabled = false;
						this.MW_TC_S.IsEnabled = false;
						this.ControlCt.IsEnabled = false;
						this.ControlS.IsEnabled = false;
						BotScripts.on_Disconnected( );
						break;
					case XmppConnectionState.Registered:
						break;
					case XmppConnectionState.Registering:
						break;
					case XmppConnectionState.Securing:
						break;
					case XmppConnectionState.SessionStarted:
						this.MW_M_B_Co.IsChecked = true;
						this.MW_M_B_Ch.IsEnabled = true;
						this.MW_TC_Ct.IsEnabled = true;
						this.MW_TC_S.IsEnabled = true;
						this.ControlCt.IsEnabled = true;
						this.ControlS.IsEnabled = true;
						BotScripts.on_Connected( );
						break;
					case XmppConnectionState.StartCompression:
						break;
					case XmppConnectionState.StartSession:
						break;
				}
				if ((state.ToString( ) + " ").LastIndexOf("ing ") > 0)
					this.SBI_PB_XMPP.IsIndeterminate = true;
				else
					this.SBI_PB_XMPP.IsIndeterminate = false;
				this.SBI_LS_XMPP.Content = state.ToString( );
			}
		}
		public void xmpp_consolechat(object sender, agsXMPP.protocol.client.Message msg, object data) {
			/* Przyszła nowa wiadomość dla consolechat */
			App.xmpp.Logs.Add(String.Format("Nowa wiadomość od {0}", msg.From.User), LogFlags.XMPP, LogType.Info);
		}
		#endregion

		#region Zdalne instrukcje
		delegate void StateBotD(string tekst, bool type);
		public void StateBot(string tekst, bool type) {
			if (!this.Dispatcher.CheckAccess( )) {
				this.Dispatcher.Invoke(new StateBotD(StateBot), DispatcherPriority.Normal, new object[ ] { tekst, type });
			} else {
				if (type) {
					this.SBI_PB_Bot.Value = Convert.ToInt16(tekst);
				} else {
					if (this.SBI_PB_Bot.Value != 0 || this.SBI_PB_Bot.Value != 100) {
						if ((tekst + " ").LastIndexOf("ing ") > 0) {
							this.SBI_PB_Bot.IsIndeterminate = true;
							this.SBI_PB_Bot.Value = 0;
						} else {
							this.SBI_PB_Bot.IsIndeterminate = false;
							this.SBI_PB_Bot.Value = 100;
						}
					}
					this.SBI_LS_Bot.Content = tekst;
				}
			}
		}
		delegate void CheckStatusD(Presence info);
		public void CheckStatus(Presence info) {
			if (!this.Dispatcher.CheckAccess( )) {
				this.Dispatcher.Invoke(new CheckStatusD(CheckStatus), DispatcherPriority.Normal, new object[ ] { info });
			} else {
				clearAllStatusTSMI( );
				switch (JFunctions.getStatusInt(info)) {
					case 0:
						this.MW_M_B_Ch_Di.IsChecked = true;
						break;
					case 1:
						this.MW_M_B_Ch_Co.IsChecked = true;
						break;
					case 2:
						this.MW_M_B_Ch_Ff.IsChecked = true;
						break;
					case 3:
						this.MW_M_B_Ch_Aw.IsChecked = true;
						break;
					case 4:
						this.MW_M_B_Ch_Xa.IsChecked = true;
						break;
					case 5:
						this.MW_M_B_Ch_Dn.IsChecked = true;
						break;
					default:
						this.MW_M_B_Ch_In.IsChecked = true;
						break;
				}
			}
		}
		#endregion

		#region Instrukcje okna
		private void clearAllStatusTSMI( ) {
			this.MW_M_B_Ch_Di.IsChecked = false;
			this.MW_M_B_Ch_Co.IsChecked = false;
			this.MW_M_B_Ch_Ff.IsChecked = false;
			this.MW_M_B_Ch_Aw.IsChecked = false;
			this.MW_M_B_Ch_Xa.IsChecked = false;
			this.MW_M_B_Ch_Dn.IsChecked = false;
			this.MW_M_B_Ch_In.IsChecked = false;
		}
		private void SHwindow( ) {
			if (this.Opacity == 1) {
				this.Opacity = 0;
				this.Hide( );
			} else {
				this.Show( );
				this.Opacity = 1;
			}
		}
		#endregion

		#region Zdarzenia okna
		private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
			if (this.SBI_LS_XMPP.Content.ToString( ) != "Disconnected" && this.SBI_LS_XMPP.Content.ToString( ).ToLower( ).IndexOf("error") == -1) {
				switch (MessageBox.Show("You must disconnect with server first!\nDo you want close connection before program will be closed?", "Error!", MessageBoxButton.YesNoCancel, MessageBoxImage.Warning)) {
					case MessageBoxResult.Yes:
						App.xmpp.disconnect( );
						while (this.SBI_LS_XMPP.Content.ToString( ) != "Disconnected" && e.Cancel == false) {
							if (MessageBox.Show("Disconnection in progress...", "Wait!", MessageBoxButton.OKCancel, MessageBoxImage.Information) == MessageBoxResult.Cancel) {
								e.Cancel = true;
							}
						}
						break;
					case MessageBoxResult.No:
						break;
					case MessageBoxResult.Cancel:
						e.Cancel = true;
						break;
				};
			}
		}
		private void NI_Icon_Click(object sender, EventArgs e) {
			SHwindow( );
		}
		private void MW_M_B_Co_Click(object sender, RoutedEventArgs e) {
			if (App.xmpp.XmppConnectionState != XmppConnectionState.Disconnected) {
				App.xmpp.disconnect( );
			}
			if (App.xmpp.XmppConnectionState == XmppConnectionState.Disconnected || App.xmpp.XmppConnectionState == XmppConnectionState.Connecting) {
				App.xmpp.connect( );
			}
		}
		private void MW_M_B_Ch_Co_Click(object sender, RoutedEventArgs e) {
			App.xmpp.Me.PresenceType = PresenceType.available;
			App.xmpp.Me.ShowType = ShowType.NONE;
			App.xmpp.presenceTransports( );
			clearAllStatusTSMI( );
			//this.TSMI_1_1_connected.CheckState = CheckState.Indeterminate;
		}
		private void MW_M_B_Ch_Ff_Click(object sender, RoutedEventArgs e) {
			App.xmpp.Me.PresenceType = PresenceType.available;
			App.xmpp.Me.ShowType = ShowType.chat;
			App.xmpp.presenceTransports( );
			clearAllStatusTSMI( );
			// this.TSMI_1_1_chat.CheckState = CheckState.Indeterminate;
		}
		private void MW_M_B_Ch_Aw_Click(object sender, RoutedEventArgs e) {
			App.xmpp.Me.PresenceType = PresenceType.available;
			App.xmpp.Me.ShowType = ShowType.away;
			App.xmpp.presenceTransports( );
			clearAllStatusTSMI( );
			//this.TSMI_1_1_away.CheckState = CheckState.Indeterminate;
		}
		private void MW_M_B_Ch_Xa_Click(object sender, RoutedEventArgs e) {
			App.xmpp.Me.PresenceType = PresenceType.available;
			App.xmpp.Me.ShowType = ShowType.xa;
			App.xmpp.presenceTransports( );
			clearAllStatusTSMI( );
			//this.TSMI_1_1_xa.CheckState = CheckState.Indeterminate;
		}
		private void MW_M_B_Ch_Dn_Click(object sender, RoutedEventArgs e) {
			App.xmpp.Me.PresenceType = PresenceType.available;
			App.xmpp.Me.ShowType = ShowType.dnd;
			App.xmpp.presenceTransports( );
			clearAllStatusTSMI( );
			//this.TSMI_1_1_dnd.CheckState = CheckState.Indeterminate;
		}
		private void MW_M_B_Ch_In_Click(object sender, RoutedEventArgs e) {
			App.xmpp.Me.PresenceType = PresenceType.invisible;
			App.xmpp.Me.ShowType = ShowType.NONE;
			App.xmpp.presenceTransports( );
			clearAllStatusTSMI( );
			//this.TSMI_1_1_invisible.CheckState = CheckState.Indeterminate;
		}
		private void MW_M_B_Ch_Di_Click(object sender, RoutedEventArgs e) {
			App.xmpp.Me.PresenceType = PresenceType.unavailable;
			App.xmpp.Me.ShowType = ShowType.NONE;
			App.xmpp.presenceTransports( );
			clearAllStatusTSMI( );
			//this.TSMI_1_1_disconnected.CheckState = CheckState.Indeterminate;
		}
		private void MW_M_B_Ch_Sd_Click(object sender, RoutedEventArgs e) {
			//SD = new Dialog.SetDescBox();
			//SD.ShowDialog();
		}
		private void MW_M_B_H_Click(object sender, RoutedEventArgs e) {
			SHwindow( );
		}
		private void MW_M_B_E_Click(object sender, RoutedEventArgs e) {
			this.Close( );
		}
		private void MW_M_L_L_Bl_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_L_L_Cl_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_L_L_Xl_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_L_L_Al_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_L_S_Bl_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_L_S_Cl_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_L_S_Xl_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_L_S_Al_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_L_I_Bl_Click(object sender, RoutedEventArgs e) {
			BotScripts.on_Start( );
		}
		private void MW_M_L_I_Cl_Click(object sender, RoutedEventArgs e) {
			BotScripts.on_Message("madzia@aqq.eu", "Elo bocik\r\nco tam slychac?", "", "", new DateTime(2010, 01, 23, 18, 49, 20), 0);
		}
		private void MW_M_L_I_Xl_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_L_I_Al_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_L_E_Bl_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_L_E_Cl_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_L_E_Xl_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_L_E_Al_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_L_C_Bl_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_L_C_Cl_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_L_C_Xl_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_L_C_Al_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_T_A_DNU_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_T_A_DBU_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_T_O_Click(object sender, RoutedEventArgs e) {
			Options = new Windows.OptionsWindow( );
			Options.Owner = this;
			if (Options.ShowDialog( ) == true) {
				this.resetXMPP( );
				/*case DialogResult.OK:
					if (Global.xmpp.Client.XmppConnectionState != XmppConnectionState.Disconnected) {
						Global.xmpp.disconnect();
						reloadXMPP();
						Global.xmpp.connect();
					} else {
						reloadXMPP();
					}
					break;
				case DialogResult.Yes:
					if (Global.xmpp.Client.XmppConnectionState != XmppConnectionState.Disconnected) {
						Global.xmpp.disconnect();
						reloadXMPP();
						Global.xmpp.connect();
					} else {
						reloadXMPP();
					}
					break;
				case DialogResult.Ignore:
					if (Global.xmpp.Client.XmppConnectionState != XmppConnectionState.Disconnected) {
						Global.xmpp.disconnect();
						reloadXMPP();
						Global.xmpp.connect();
					} else {
						reloadXMPP();
					}
					break;*/
			}
		}
		private void MW_M_H_D_Click(object sender, RoutedEventArgs e) {

		}
		private void MW_M_H_U_Click(object sender, RoutedEventArgs e) {
			Updates = new Windows.UpdateWindow( );
			Updates.Owner = this;
			Updates.ShowDialog( );
		}
		private void MW_M_H_A_Click(object sender, RoutedEventArgs e) {
			About = new Windows.AboutWindow( );
			About.Owner = this;
			About.ShowDialog( );
		}
		#endregion
	}
}